/* eslint-disable import/order */
import { useSettings } from "@/store/settingStore";
import { useThemeToken } from "@/theme/hooks";
import { commonService } from "@/api/services/commonService";
import { message } from "antd";
import "@wangeditor/editor/dist/css/style.css";
import { Editor, Toolbar } from "@wangeditor/editor-for-react";
import { IDomEditor, IEditorConfig, IToolbarConfig } from "@wangeditor/editor";
import { useState, useEffect } from "react";
import { StyledEditor } from "./styles";

interface Props {
	value?: string;
	onChange?: (html: string) => void;
	height?: number;
}

/**
 * 从html代码中匹配返回图片标签img的属性src的值的集合
 * @param htmlData
 * @return Array
 */
function findAllImgSrcsFromHtml(htmlData: string): string[] {
	if (!htmlData || typeof htmlData !== "string") {
		return [];
	}

	// 更健壮的正则表达式
	const imgReg = /<img[^>]+src\s*=\s*['"]([^'"]+)['"][^>]*>/gi;
	const srcArr: string[] = [];
	let match;

	// 使用while循环来匹配所有图片
	while ((match = imgReg.exec(htmlData)) !== null) {
		if (match[1]) {
			srcArr.push(match[1]);
		}
	}

	return srcArr;
}

/**
 * 从rtf内容中匹配返回图片数据的集合
 * @param rtfData
 * @return Array
 */
function extractImageDataFromRtf(rtfData) {
	if (!rtfData) {
		return [];
	}

	const regexPictureHeader =
		/{\\pict[\s\S]+?({\\\*\\blipuid\s?[\da-fA-F]+)[\s}]*/;
	const regexPicture = new RegExp(
		"(?:(" + regexPictureHeader.source + "))([\\da-fA-F\\s]+)\\}",
		"g",
	);
	const images = rtfData.match(regexPicture);
	const result = [];

	if (images) {
		for (const image of images) {
			let imageType = false;

			if (image.includes("\\pngblip")) {
				imageType = "image/png";
			} else if (image.includes("\\jpegblip")) {
				imageType = "image/jpeg";
			}

			if (imageType) {
				result.push({
					hex: image
						.replace(regexPictureHeader, "")
						.replace(/[^\da-fA-F]/g, ""),
					type: imageType,
				});
			}
		}
	}

	return result;
}

/**
 * 将html内容中img标签的属性值替换
 * @param htmlData html内容
 * @param imageSrcs html中img的属性src的值的集合
 * @param imagesHexSources rtf中图片数据的集合，与html内容中的img标签对应
 * @param isBase64Data 是否是Base64的图片数据
 * @return String
 */
function replaceImagesFileSourceWithInlineRepresentation(
	htmlData,
	imageSrcs,
	imagesHexSources,
	isBase64Data = true,
) {
	if (imageSrcs.length === imagesHexSources.length) {
		for (let i = 0; i < imageSrcs.length; i++) {
			const newSrc = isBase64Data
				? `data:${imagesHexSources[i].type};base64,${_convertHexToBase64(imagesHexSources[i].hex)}`
				: imagesHexSources[i];

			htmlData = htmlData.replace(imageSrcs[i], newSrc);
		}
	}

	return htmlData;
}

/**
 * 十六进制转base64
 */
function _convertHexToBase64(hexString) {
	return btoa(
		hexString
			.match(/\w{2}/g)
			.map((char) => {
				return String.fromCharCode(parseInt(char, 16));
			})
			.join(""),
	);
}

async function getClipboardContents() {
	const data = [];
	let isContinue = 0;
	try {
		const clipboardItems = await navigator.clipboard.read();
		console.log(clipboardItems);
		for (const clipboardItem of clipboardItems) {
			if (clipboardItem.types.includes("text/html")) {
				let content = "";
				const type = "text/html";
				const blob = await clipboardItem.getType(type);
				content = await blob.text();

				data.push({
					type,
					content,
				});
				continue;
			}

			// if (clipboardItem.types.includes("text/rtf")) {
			// 	const type = "text/rtf";
			// 	const blob = await clipboardItem.getType(type);
			// 	const rtfData = await blob.text();
			// 	const imageSrcs = findAllImgSrcsFromHtml(rtfData);
			// 	const imagesHexSources = extractImageDataFromRtf(rtfData);
			// 	const content = replaceImagesFileSourceWithInlineRepresentation(
			// 		rtfData,
			// 		imageSrcs,
			// 		imagesHexSources,
			// 	);
			// 	data.push({
			// 		type,
			// 		content,
			// 	});
			// 	continue;
			// }

			isContinue = 1;
			for (let type of clipboardItem.types) {
				const blob = await clipboardItem.getType(type);
				let content = "";
				if (clipboardItem.types.includes("text/html")) {
					content = await blob.text();
					type = "text/html";
					isContinue = 0;
				}

				if (type.includes("image")) {
					const file = new File([blob], "clipboard_image.png", {
						type: type,
					});
					const result = await commonService.uploadFile(file);
					content = result.url;
				}
				if (type === "text/plain") {
					content = await blob.text();
				}
				data.push({
					type,
					content,
				});
			}
		}
	} catch (err) {
		console.error(err.name, err.message);
	}
	console.log(data);
	return data;
}

export default function RichTextEditor({
	value = "",
	onChange,
	height = 500,
}: Props) {
	const token = useThemeToken();
	const { themeMode } = useSettings();
	const [editor, setEditor] = useState<IDomEditor | null>(null);
	const [html, setHtml] = useState(value);

	useEffect(() => {
		console.log(value);
		setHtml(value);
	}, [value]);

	const toolbarConfig: Partial<IToolbarConfig> = {
		excludeKeys: [],
	};

	const editorConfig: Partial<IEditorConfig> = {
		placeholder: "请输入内容...",
		MENU_CONF: {
			uploadImage: {
				async customUpload(file: File, insertFn: any) {
					try {
						const formData = new FormData();
						formData.append("file", file);
						const response = await commonService.uploadFile(file);
						insertFn(response.url);
					} catch (error) {
						message.error("图片上传失败");
					}
				},
			},
		},
		customPaste: (editor: IDomEditor, event: ClipboardEvent) => {
			let rtf = event.clipboardData.getData("text/rtf");

			getClipboardContents().then(async (data) => {
				console.log(data);
				for (const item of data) {
					console.log(item);
					if (item.type.includes("image")) {
						console.log("图片");
						console.log(item.content);
						editor.insertNode({
							type: "image",
							src: item.content,
							alt: "图片",
							children: [{ text: "" }],
						});
					}
					if (item.type === "text/html") {
						if (rtf) {
							let html = item.content.replace(/text\-indent:\-(.*?)pt/gi, "");
							// 移除 Word 的条件注释标签
							// 移除所有 HTML 注释
							// html = html.replace(/<!--[\s\S]*?-->/g, "");
							// 清理 Word 特定的 XML 命名空间标签
							html = html.replace(/<[v|o]:[^>]+>/gi, ""); // 移除所有 v: 和 o: 开头的标签
							html = html.replace(/<\/[v|o]:[^>]+>/gi, ""); // 移除所有 v: 和 o: 结尾的标签
							// 清理 Word 特定的 XML 命名空间标签
							//  html = html.replace(/<img([^>]*)(?!\/)>/gi, "<img$1 />");
							// html = html.replace(/<img([^>]*)(?!\/)>/gi, "<img$1 />");
							//给img标签添加个闭/
							console.log(html);
							const imgSrcs = findAllImgSrcsFromHtml(html);
							console.log("imgSrcs", imgSrcs);

							// 如果有
							if (imgSrcs && Array.isArray(imgSrcs) && imgSrcs.length) {
								// 从rtf内容中查找图片数据
								const rtfImageData = extractImageDataFromRtf(rtf);
								console.log(rtfImageData);
								// 如果找到
								if (rtfImageData.length) {
									// TODO：此处可以将图片上传到自己的服务器上
									// 将 base64 图片数据转换为文件并上传到服务器
									const uploadPromises = rtfImageData.map(async (imageData) => {
										try {
											// 将十六进制转换为 base64
											const base64Data = `data:${imageData.type};base64,${_convertHexToBase64(imageData.hex)}`;

											// 将 base64 转换为 Blob
											const response = await fetch(base64Data);
											const blob = await response.blob();

											// 创建文件对象
											const file = new File([blob], "rtf-image.png", {
												type: imageData.type,
											});

											// 上传文件
											const result = await commonService.uploadFile(file);
											return result.url;
										} catch (error) {
											console.error("图片上传失败:", error);
											message.error("图片上传失败");
											return null;
										}
									});

									// // 等待所有图片上传完成
									const uploadedUrls = await Promise.all(uploadPromises);

									console.log(uploadedUrls);
									console.log(html, imgSrcs, uploadedUrls);
									// // 替换 HTML 中的图片链接
									html = replaceImagesFileSourceWithInlineRepresentation(
										html,
										imgSrcs,
										uploadedUrls.filter(Boolean), // 过滤掉上传失败的图片
										false, // 设置为 false 表示使用 URL 而不是 base64
									);
									console.log(html);
									// editor.dangerouslyInsertHtml(
									// 	'<img width="170" height="369" src="https://www.chuangmeng888.com/uploads/20250108/ab0f384092bca33e311d2d220974239d.png" alt="1d4441ed8174c3eb80c2f88bf6d8587" v:shapes="图片_x0020_23" />',
									// );
									//只留下正常的标签

									// html = html.replace(/<[v|o]:[^>]+>/gi, ""); // 移除所有 v: 和 o: 开头的标签
									// html = html.replace(/<\/[v|o]:[^>]+>/gi, ""); // 移除所有 v: 和 o: 结尾的标签

									// 2. 使用 sanitize-html 清理和规范化 HTML

									// 添加 span 转换为 p 的逻辑
									html = html.replace(
										/<span([^>]*)>([\s\S]*?)<\/span>/gi,
										"<div$1>$2</div>",
									);
									html = html.replace(
										/<b([^>]*)>([\s\S]*?)<\/b>/gi,
										"<div$1>$2</div>",
									);
									console.log(html);

									// // 执行替换：将html内容中的img标签的src替换成ref中的图片数据，如果上面上传了则为图片路径
									// console.log(imgSrcs, rtfImageData);

									// html = replaceImagesFileSourceWithInlineRepresentation(
									// 	html,
									// 	imgSrcs,
									// 	rtfImageData,
									// );
									// console.log(html);
									// editor.dangerouslyInsertHtml(html);
								}
							}
							editor.dangerouslyInsertHtml(html);
						} else {
							console.log("html");
							editor.dangerouslyInsertHtml(item.content);
						}
					}
					if (item.type === "text/plain") {
						console.log("plain");
						editor.insertText(item.content);
					}
					if (item.type === "text/rtf") {
						editor.dangerouslyInsertHtml(item.content);
					}
				}
			});

			// 阻止默认的粘贴行为
			event.preventDefault();
			console.log("禁止");
			return false;

			// try {
			// 	event.preventDefault();
			// 	// 使用 Clipboard API 读取剪贴板内容
			// 	const clipboardItems = await navigator.clipboard.read();
			// 	let hasHandledContent = false;
			// 	console.log(clipboardItems);
			// 	for (const item of clipboardItems) {
			// 		// 处理图片类型
			// 		const imageTypes = item.types.filter((type) =>
			// 			type.startsWith("image/"),
			// 		);
			// 		for (const imageType of imageTypes) {
			// 			try {
			// 				const blob = await item.getType(imageType);
			// 				const file = new File(
			// 					[blob],
			// 					`clipboard_image.${imageType.split("/")[1]}`,
			// 					{ type: imageType },
			// 				);
			// 				const result = await commonService.uploadFile(file);
			// 				editor.insertNode({
			// 					type: "image",
			// 					src: result.url,
			// 					alt: file.name,
			// 					children: [{ text: "" }],
			// 				});
			// 				hasHandledContent = true;
			// 			} catch (error) {
			// 				console.error("处理图片失败:", error);
			// 				message.error("图片上传失败");
			// 			}
			// 		}

			// 		// 处理 HTML 内容
			// 		if (item.types.includes("text/html")) {
			// 			try {
			// 				const htmlBlob = await item.getType("text/html");
			// 				const html = await htmlBlob.text();

			// 				if (html) {
			// 					// 列表缩进会超出边框，直接过滤掉
			// 					let processedHtml = html.replace(
			// 						/text\-indent:\-(.*?)pt/gi,
			// 						"",
			// 					);

			// 					// 从html内容中查找图片
			// 					const imgSrcs = findAllImgSrcsFromHtml(processedHtml);

			// 					editor.dangerouslyInsertHtml(processedHtml);
			// 					hasHandledContent = true;
			// 				}
			// 			} catch (error) {
			// 				console.error("处理HTML内容失败:", error);
			// 			}
			// 		}
			// 		console.log(hasHandledContent);
			// 		// 如果没有处理过任何内容，尝试处理纯文本
			// 		if (!hasHandledContent && item.types.includes("text/plain")) {
			// 			try {
			// 				const textBlob = await item.getType("text/plain");
			// 				const text = await textBlob.text();
			// 				editor.insertText(text);
			// 				console.log(text);
			// 				hasHandledContent = true;
			// 			} catch (error) {
			// 				console.error("处理文本内容失败:", error);
			// 			}
			// 		}
			// 	}

			// 	// 如果已经处理过内容，阻止默认粘贴行为
			// 	// if (hasHandledContent) {
			// 	// 	event.preventDefault();
			// 	// 	return false;
			// 	// }

			// 	// 如果没有处理任何内容，允许默认粘贴行为
			// 	return false;
			// } catch (error) {
			// 	console.error("处理剪贴板内容失败:", error);
			// 	// 发生错误时，允许默认粘贴行为
			// 	return true;
			// }
		},
		customPaste1: async (editor: IDomEditor, event: ClipboardEvent) => {
			// 阻止默认粘贴行为
			event.preventDefault();

			const clipboardData = event.clipboardData;
			if (!clipboardData) return;

			// 处理文本内容
			const text = clipboardData.getData("text/plain");
			const html = clipboardData.getData("text/html");

			// 如果有HTML内容，优先处理HTML
			if (html) {
				const tempDiv = document.createElement("div");
				tempDiv.innerHTML = html;
				const images = tempDiv.getElementsByTagName("img");

				// 处理HTML中的图片
				if (images.length > 0) {
					const imagePromises = Array.from(images).map(async (img) => {
						const imgSrc = img.src;
						if (imgSrc) {
							try {
								// 处理base64图片
								if (imgSrc.startsWith("data:image")) {
									const response = await fetch(imgSrc);
									const blob = await response.blob();
									const file = new File([blob], "image.png", {
										type: blob.type,
									});
									const formData = new FormData();
									formData.append("file", file);
									const uploadResponse = await commonService.uploadFile(file);
									return {
										type: "image",
										src: uploadResponse.url,
										alt: "pasted-image",
										children: [{ text: "" }],
									};
								}

								// 处理远程图片URL
								try {
									// 先尝试直接获取图片
									const response = await fetch(imgSrc, {
										mode: "cors",
										credentials: "same-origin",
										headers: {
											"Access-Control-Allow-Origin": "*",
										},
									});
									const blob = await response.blob();
									const file = new File([blob], "image.png", {
										type: blob.type,
									});
									const formData = new FormData();
									formData.append("file", file);
									const uploadResponse = await commonService.uploadFile(file);
									return {
										type: "image",
										src: uploadResponse.url,
										alt: "pasted-image",
										children: [{ text: "" }],
									};
								} catch (fetchError) {
									// 如果直接获取失败，尝试通过后端代理获取
									const formData = new FormData();
									formData.append("url", imgSrc);
									const uploadResponse =
										await commonService.uploadByUrl(imgSrc);
									return {
										type: "image",
										src: uploadResponse.url,
										alt: "pasted-image",
										children: [{ text: "" }],
									};
								}
							} catch (error) {
								console.log(error);
								message.error("图片上传失败");
								return null;
							}
						}
						return null;
					});

					const imageNodes = await Promise.all(imagePromises);
					// 过滤掉上传失败的图片，依次插入成功的图片
					imageNodes.filter(Boolean).forEach((node) => {
						editor.insertNode(node);
					});
				} else {
					// 如果HTML中没有图片，插入文本
					if (text) editor.insertText(text);
				}
			} else {
				// 如果没有HTML，直接插入文本
				editor.insertText(text);
			}

			// 处理剪贴板中的图片文件
			const items = Array.from(clipboardData.items);
			const imageItems = items.filter(
				(item) => item.type.indexOf("image") !== -1,
			);

			if (imageItems.length > 0) {
				const uploadPromises = imageItems.map(async (item) => {
					const file = item.getAsFile();
					if (file) {
						try {
							const formData = new FormData();
							formData.append("file", file);
							const response = await commonService.uploadFile(file);
							return {
								type: "image",
								src: response.url,
								alt: file.name,
								children: [{ text: "" }],
							};
						} catch (error) {
							console.log(error);
							message.error("图片上传失败");
							return null;
						}
					}
					return null;
				});

				const nodes = await Promise.all(uploadPromises);
				// 过滤掉上传失败的图片，依次插入成功的图片
				nodes.filter(Boolean).forEach((node) => {
					editor.insertNode(node);
				});
			}

			return false;
		},
	};

	useEffect(() => {
		return () => {
			if (editor == null) return;
			editor.destroy();
			setEditor(null);
		};
	}, [editor]);

	return (
		<StyledEditor $token={token} $thememode={themeMode}>
			<div style={{ border: "1px solid #ccc", zIndex: 100 }}>
				<Toolbar
					editor={editor}
					defaultConfig={toolbarConfig}
					mode={themeMode === "dark" ? "dark" : "default"}
					style={{ borderBottom: "1px solid #ccc" }}
				/>

				<Editor
					defaultConfig={editorConfig}
					value={html}
					onCreated={setEditor}
					onChange={(editor) => {
						const content = editor.getHtml();
						const isEmpty = content === "<p><br></p>" || content === "";
						const finalContent = isEmpty ? "" : content;
						setHtml(finalContent);
						onChange?.(finalContent);
					}}
					mode={themeMode === "dark" ? "dark" : "default"}
					style={{ height: `${height}px`, overflowY: "hidden" }}
				/>
			</div>
		</StyledEditor>
	);
}
